package com.honey.compilation.sql.ddl;

import com.honey.compilation.sql.SqlKeyWord;
import com.honey.compilation.sql.SqlScript;
import com.honey.core.builder.CharacterBuilder;
import com.honey.core.builder.CharacterBuilderFactory;
import com.honey.core.compiler.CompilationException;

/**
 * Set 事务级别的命令,SQL 92中定义如下: <br />
 * &lt;set transaction statement&gt;    ::= SET TRANSACTION &lt;transaction mode&gt; <br />
 * &lt;transaction mode&gt;    ::=&lt;isolation level&gt;<br />
 * &lt;isolation level&gt;    ::=   ISOLATION LEVEL &lt;level of isolation&gt;<br />
 * &lt;level of isolation&gt;    ::=  READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
 * 
 * @author Administrator
 * 
 */
public final class SetTransactionLevel extends SetTransaction implements SqlScript {
	
	private IsolationLevel isolationLevel ;
	
	
	/**
	 * 设定事务的隔离级别
	 * @param isolationLevel
	 */
	public void setIsolationLevel(IsolationLevel isolationLevel ){
		this.isolationLevel = isolationLevel;
	}
	
	/**
	 * 设定数据库默认事务级别
	 */
	public void setDefaultLevel(){
		isolationLevel = null;
	}
	
	/**
	 * 未授权读取:允许脏读取，但不允许更新丢失。
	 */
	public void setReadUncommittedLevel(){
		this.isolationLevel = IsolationLevel.READ_UNCOMMITTED;
	}
	
	/**
	 * 授权读取:允许不可重复读取，但不允许脏读取
	 */
	public void setReadCommittedLevel(){
		this.isolationLevel = IsolationLevel.READ_COMMITTED;
	}
	
	
	/**
	 * 可重复读取 : 禁止不可重复读取和脏读取，但是有时可能出现幻影数据
	 */
	public void setRepeatableReadLevel(){
		this.isolationLevel = IsolationLevel.REPEATABLE_READ;
	}
	
	
	/**
	 * 序列化 : 提供严格的事务隔离。
	 */
	public void setSerializableLevel(){
		this.isolationLevel = IsolationLevel.SERIALIZABLE;
	}
	
	
	
	public CharacterBuilder compiledContent(int indentLevel )throws CompilationException {
		CharacterBuilder answer = CharacterBuilderFactory.createC16StringBuilder() ;
		if(isolationLevel != null){
			answer.append( super.compiledContent(indentLevel) );
			answer.append( SqlKeyWord.ISOLATION )
			.append(SqlKeyWord.LEVEL)
			.append(isolationLevel)
			.append(SqlKeyWord.OPERATION_SEMICOLON)
			;
		}
		return answer;
	}
	
	
	public CharacterBuilder compiledContent() throws CompilationException{
		return this.compiledContent(0);
		
	}
	
	
	/**
	 * 事务隔离级别枚举,SQL 92 中定义事务定义的隔离级别:<br />
	 * 	&lt;level of isolation&gt;    ::= <br />
	 * 	READ UNCOMMITTED <br />
	 * 	|     READ COMMITTED <br />
	 * 	|     REPEATABLE READ <br />
	 * 	|     SERIALIZABLE <br />
	 * 
	 * @author Administrator
	 *
	 */
	public enum IsolationLevel{
		
		/**
		 * 未授权读取:允许脏读取，但不允许更新丢失。<br />
		 * 如果一个事务已经开始写数据，则另外一个数据则不允许同时进行写操作，但允许其他事务读此行数据。
		 * 该隔离级别可以通过“排他写锁”实现。<br />
		 */
		READ_UNCOMMITTED("READ UNCOMMITTED "),
		
		
		/**
		 * 授权读取:允许不可重复读取，但不允许脏读取<br />
		 * 这可以通过“瞬间共享读锁”和“排他写锁”实现。
		 * 读取数据的事务允许其他事务继续访问该行数据，但是未提交的写事务将会禁止其他事务访问该行。<br>
		 */
		READ_COMMITTED ("READ COMMITTED "),
		
		
		/**
		 * 可重复读取 : 禁止不可重复读取和脏读取，但是有时可能出现幻影数据<br />
		 * 这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务
		 * （但允许读事务），写事务则禁止任何其他事务。<br>
		 */
		REPEATABLE_READ  ("REPEATABLE READ "),
		 
		
		/**
		 * 序列化 : 提供严格的事务隔离。<br />
		 * 它要求事务序列化执行，事务只能一个接着一个地执行，但不能并发执行,
		 * 如果仅仅通过“行级锁”是无法实现事务序列化的，必须通过其他机制保证新插入
		 * 的数据不会被刚执行查询操作的事务访问到。<br />
		 * 
		 */
		SERIALIZABLE  ("SERIALIZABLE "),
		
		;
		private final String level;
		
		private IsolationLevel (String level){
			this.level =  level;
		}
		
		@Override
		public String toString() {
			
			return level;
		}
		
		
	}
}
